<template>
  <div class="editable-element" ref="elementRef" :id="`editable-element-${elementInfo.id}`" :style="{
    zIndex: elementIndex
  }">
    <component :is="currentElementComponent" :elementInfo="elementInfo" :selectElement="selectElement"
      :contextmenu="contextmenu"></component>
  </div>
</template>

<script setup lang="ts">
import { PropType, defineProps, computed } from 'vue'
import { ElementTypes, PPTElement } from '@/types/slides'
import { ContextmenuItem } from '@/components/Contextmenu/types'
import { ElementAlignCommands, ElementOrderCommands } from '@/types/edit'

import useOrderElement from '@/hooks/useOrderElement'
import useAlignElementToCanvas from '@/hooks/useAlignElementToCanvas'
import useDeleteElement from '@/hooks/useDeleteElement'
import useCopyAndPasteElement from '@/hooks/useCopyAndPasteElement'
import useSelectAllElement from '@/hooks/useSelectAllElement'
import useLockElement from '@/hooks/useLockElement'
import useCombineElement from '@/hooks/useCombineElement'

import LineElement from '@/views/components/element/LineElement/index.vue'
import ChartElement from '@/views/components/element/ChartElement/index.vue'
import TableElement from '@/views/components/element/TableElement/index.vue'
import LatexElement from '@/views/components/element/LatexElement/index.vue'
import AudioElement from '@/views/components/element/AudioElement/index.vue'
import VideoElement from '@/views/components/element/VideoElement/index.vue'
import ShapeElement from '@/views/components/element/ShapeElement/index.vue'
import TextElement from '@/views/components/element/TextElement/index.vue'
import ImageElement from '@/views/components/element/ImageElement/index.vue'

const props = defineProps({
  elementInfo: { // 元素信息
    type: Object as PropType<PPTElement>,
    required: true
  },
  elementIndex: { // 元素索引
    type: Number,
    required: true
  },
  isMultiSelect: { // 元素是否处于多选状态
    type: Boolean,
    required: true
  },
  selectElement: { // 选择的元素
    type: Function as PropType<(e: MouseEvent, element: PPTElement, canMove?: boolean) => void>,
    required: true
  },
  openLinkDialog: { // 元素链接对话框
    type: Function as PropType<() => void>,
    required: true
  }
})

const currentElementComponent = computed(() => {
  const elementTypeMap = {
    [ElementTypes.IMAGE]: ImageElement,
    [ElementTypes.TEXT]: TextElement,
    [ElementTypes.SHAPE]: ShapeElement,
    [ElementTypes.LINE]: LineElement,
    [ElementTypes.CHART]: ChartElement,
    [ElementTypes.TABLE]: TableElement,
    [ElementTypes.LATEX]: LatexElement,
    [ElementTypes.VIDEO]: VideoElement,
    [ElementTypes.AUDIO]: AudioElement,
  }

  return elementTypeMap[props.elementInfo.type] || null
})

// 对元素的层级进行调整
const { orderElement } = useOrderElement()
// 将选中的元素对齐画布
const { alignElementToCanvas } = useAlignElementToCanvas()
// 对选中的元素进行锁定/解锁
const { lockElement, unlockElement } = useLockElement()
const { combineElements, unCombineElements } = useCombineElement()
const { selectAllElement } = useSelectAllElement()
const { copyElement, pasteElement, cutElement } = useCopyAndPasteElement()
const { deleteElement } = useDeleteElement()

const contextmenu = (): ContextmenuItem[] => {
  if (props.elementInfo.lock) {
    return [
      {
        text: '解锁',
        handler: () => unlockElement(props.elementInfo)
      }
    ]
  }
  return [
    {
      text: '剪切',
      subText: 'Ctrl + X',
      handler: cutElement
    },
    {
      text: '复制',
      subText: 'Ctrl + C',
      handler: copyElement
    },
    {
      text: '粘贴',
      subText: 'Ctrl + V',
      handler: pasteElement
    },
    { divider: true },
    {
      text: '水平居中',
      handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL),
      children: [
        { text: '水平垂直居中', handler: () => alignElementToCanvas(ElementAlignCommands.CENTER) },
        { text: '水平居中', handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL) },
        { text: '左对齐', handler: () => alignElementToCanvas(ElementAlignCommands.LEFT) },
        { text: '右对齐', handler: () => alignElementToCanvas(ElementAlignCommands.RIGHT) }
      ]
    },
    {
      text: '垂直居中',
      handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL),
      children: [
        { text: '水平垂直居中', handler: () => alignElementToCanvas(ElementAlignCommands.CENTER) },
        { text: '垂直居中', handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL) },
        { text: '顶部对齐', handler: () => alignElementToCanvas(ElementAlignCommands.TOP) },
        { text: '底部对齐', handler: () => alignElementToCanvas(ElementAlignCommands.BOTTOM) }
      ]
    },
    { divider: true },
    {
      text: '置于顶层',
      disable: props.isMultiSelect && !props.elementInfo.groupId,
      handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP),
      children: [
        { text: '置于顶层', handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP) },
        { text: '上移一层', handler: () => orderElement(props.elementInfo, ElementOrderCommands.UP) }
      ]
    },
    {
      text: '置于底层',
      disable: props.elementInfo && !props.elementInfo.groupId,
      handler: () => orderElement(props.elementInfo, ElementOrderCommands.BOTTOM),
      children: [
        { text: '置于底层', handler: () => orderElement(props.elementInfo, ElementOrderCommands.BOTTOM) },
        { text: '下移一层', handler: () => orderElement(props.elementInfo, ElementOrderCommands.DOWN) }
      ]
    },
    { divider: true },
    {
      text: '设置链接',
      handler: props.openLinkDialog
    },
    {
      text: props.elementInfo.groupId ? '取消组合' : '组合',
      subText: 'Ctrl + G',
      handler: props.elementInfo.groupId ? unCombineElements : combineElements,
      hide: !props.isMultiSelect
    },
    {
      text: '全选',
      subText: 'Ctrl + A',
      handler: selectAllElement,
    },
    {
      text: '锁定',
      subText: 'Ctrl + L',
      handler: lockElement
    },
    {
      text: '删除',
      subText: 'Delete',
      handler: deleteElement
    }
  ]
}
</script>